package org.zwy.gradetrack.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.zwy.gradetrack.entity.EmployerEvaluation;
import org.zwy.gradetrack.entity.Graduate;
import org.zwy.gradetrack.entity.Indicator;
import org.zwy.gradetrack.mapper.EmployerEvaluationMapper;
import org.zwy.gradetrack.mapper.GraduateMapper;
import org.zwy.gradetrack.mapper.IndicatorMapper;
import org.zwy.gradetrack.service.EmployerEvaluationService;
import org.zwy.gradetrack.vo.EmployerEvaluationVO;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 用人单位评价Service实现类
 */

@Service
public class EmployerEvaluationServiceImpl extends ServiceImpl<EmployerEvaluationMapper, EmployerEvaluation> implements EmployerEvaluationService {

    private final IndicatorMapper indicatorMapper;
    private final GraduateMapper graduateMapper;

    public EmployerEvaluationServiceImpl(IndicatorMapper indicatorMapper, GraduateMapper graduateMapper) {
        this.indicatorMapper = indicatorMapper;
        this.graduateMapper = graduateMapper;
    }

    @Override
    public Page<EmployerEvaluationVO> pageEvaluationsWithDetails(Integer current, Integer size, Long employerId, Long graduateId, Long indicatorId) {
        Page<EmployerEvaluationVO> page = new Page<>(current, size);
        List<EmployerEvaluationVO> records = baseMapper.getEmployerEvaluationsWithDetails(page, employerId, graduateId, indicatorId);
        page.setRecords(records);
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public EmployerEvaluation createEvaluation(EmployerEvaluation evaluation) {
        // 检查是否存在重复评价 (用人单位ID, 毕业生ID, 指标点ID)
        LambdaQueryWrapper<EmployerEvaluation> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EmployerEvaluation::getEmployerId, evaluation.getEmployerId())
                .eq(EmployerEvaluation::getGraduateId, evaluation.getGraduateId())
                .eq(EmployerEvaluation::getIndicatorId, evaluation.getIndicatorId());
        if (count(wrapper) > 0) {
            throw new RuntimeException("该用人单位对该毕业生在该指标点已存在评价");
        }

        LocalDateTime now = LocalDateTime.now();
        evaluation.setCreateTime(now);
        evaluation.setUpdateTime(now);
        // 设置评价时间，如果前端没有提供，则使用当前时间
        if (evaluation.getEvaluationTime() == null) {
            evaluation.setEvaluationTime(now);
        }
        save(evaluation);
        return evaluation;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public EmployerEvaluation updateEvaluation(Long id, EmployerEvaluation evaluation) {
        EmployerEvaluation existingEvaluation = getById(id);
        if (existingEvaluation == null) {
            throw new RuntimeException("评价数据不存在");
        }

        // 检查更新后是否会产生重复评价 (如果修改了关键ID)
        if (!existingEvaluation.getEmployerId().equals(evaluation.getEmployerId()) ||
                !existingEvaluation.getGraduateId().equals(evaluation.getGraduateId()) ||
                !existingEvaluation.getIndicatorId().equals(evaluation.getIndicatorId())) {
            LambdaQueryWrapper<EmployerEvaluation> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(EmployerEvaluation::getEmployerId, evaluation.getEmployerId())
                    .eq(EmployerEvaluation::getGraduateId, evaluation.getGraduateId())
                    .eq(EmployerEvaluation::getIndicatorId, evaluation.getIndicatorId())
                    .ne(EmployerEvaluation::getId, id); // 排除当前自身
            if (count(wrapper) > 0) {
                throw new RuntimeException("更新后该用人单位对该毕业生在该指标点已存在评价");
            }
        }

        evaluation.setId(id);
        evaluation.setUpdateTime(LocalDateTime.now());
        updateById(evaluation);
        return evaluation;
    }

    @Override
    public Map<String, Object> getStatistics(Long employerId, Long graduateId, Long indicatorId) {
        Map<String, Object> statistics = new HashMap<>();
        LambdaQueryWrapper<EmployerEvaluation> wrapper = new LambdaQueryWrapper<>();

        if (employerId != null) {
            wrapper.eq(EmployerEvaluation::getEmployerId, employerId);
        }
        if (graduateId != null) {
            wrapper.eq(EmployerEvaluation::getGraduateId, graduateId);
        }
        if (indicatorId != null) {
            wrapper.eq(EmployerEvaluation::getIndicatorId, indicatorId);
        }

        List<EmployerEvaluation> evaluations = list(wrapper);

        // Calculate average score
        double averageScore = evaluations.stream()
                .mapToInt(EmployerEvaluation::getScore) // 使用 mapToInt 处理 Integer 类型
                .average()
                .orElse(0.0);
        statistics.put("averageScore", String.format("%.2f", averageScore));

        // You can add more statistics here, e.g., count by score, distribution etc.
        // For example, grouping by indicator and calculating average score for each
        Map<String, Double> indicatorAverageScores = evaluations.stream()
                .collect(Collectors.groupingBy(
                        e -> {
                            Indicator indicator = indicatorMapper.selectById(e.getIndicatorId());
                            return indicator != null ? indicator.getIndicatorName() : "未知指标";
                        },
                        Collectors.averagingDouble(e -> e.getScore() != null ? e.getScore().doubleValue() : 0.0) // 确保这里兼容 Integer
                ));
        statistics.put("indicatorAverageScores", indicatorAverageScores);

        // Grouping by graduate and calculating average score for each
        Map<String, Double> graduateAverageScores = evaluations.stream()
                .collect(Collectors.groupingBy(
                        e -> {
                            Graduate graduate = graduateMapper.selectById(e.getGraduateId());
                            return graduate != null ? graduate.getName() : "未知毕业生";
                        },
                        Collectors.averagingDouble(e -> e.getScore() != null ? e.getScore().doubleValue() : 0.0) // 确保这里兼容 Integer
                ));
        statistics.put("graduateAverageScores", graduateAverageScores);

        return statistics;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchImport(List<EmployerEvaluation> evaluations) {
        if (evaluations == null || evaluations.isEmpty()) {
            throw new RuntimeException("导入数据不能为空");
        }

        LocalDateTime now = LocalDateTime.now();
        for (EmployerEvaluation evaluation : evaluations) {
            // 检查是否存在重复评价 (用人单位ID, 毕业生ID, 指标点ID)
            LambdaQueryWrapper<EmployerEvaluation> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(EmployerEvaluation::getEmployerId, evaluation.getEmployerId())
                    .eq(EmployerEvaluation::getGraduateId, evaluation.getGraduateId())
                    .eq(EmployerEvaluation::getIndicatorId, evaluation.getIndicatorId());
            if (count(wrapper) > 0) {
                throw new RuntimeException("用人单位对毕业生在该指标点已存在重复评价: 毕业生ID " + evaluation.getGraduateId() + ", 指标点ID " + evaluation.getIndicatorId());
            }
            evaluation.setCreateTime(now);
            evaluation.setUpdateTime(now);
            // 设置评价时间，如果前端没有提供，则使用当前时间
            if (evaluation.getEvaluationTime() == null) {
                evaluation.setEvaluationTime(now);
            }
        }
        saveBatch(evaluations);
    }

    @Override
    public List<EmployerEvaluation> getEmployerStudentEvaluations(Long employerId, Long graduateId) {
        LambdaQueryWrapper<EmployerEvaluation> wrapper = new LambdaQueryWrapper<>();
        if (employerId != null) {
            wrapper.eq(EmployerEvaluation::getEmployerId, employerId);
        }
        if (graduateId != null) {
            wrapper.eq(EmployerEvaluation::getGraduateId, graduateId);
        }
        wrapper.orderByDesc(EmployerEvaluation::getCreateTime);
        return list(wrapper);
    }

    @Override
    public List<EmployerEvaluation> getStudentIndicatorEvaluations(Long graduateId, Long indicatorId) {
        LambdaQueryWrapper<EmployerEvaluation> wrapper = new LambdaQueryWrapper<>();
        if (graduateId != null) {
            wrapper.eq(EmployerEvaluation::getGraduateId, graduateId);
        }
        if (indicatorId != null) {
            wrapper.eq(EmployerEvaluation::getIndicatorId, indicatorId);
        }
        wrapper.orderByDesc(EmployerEvaluation::getCreateTime);
        return list(wrapper);
    }
}
